Skip to content

feat(skills): skills.auto_load pins skills into every new session (salvage #74060/#26840) - #92048

Merged
teknium1 merged 3 commits into
mainfrom
cursor-inspired/skills-auto-load
Sep 15, 2026
Merged

teknium1 merged 3 commits into
mainfrom
cursor-inspired/skills-auto-load

Conversation

@teknium1

Copy link
Copy Markdown
Collaborator

Summary

skills.auto_load in config.yaml now pins skills as fully loaded at the start of every new session — CLI, TUI, gateway, cron, and API agents all included — the "always-on skill" pattern Cursor shipped as Custom Modes in its Aug 19, 2026 changelog.

Salvages #74060 by @ctaylor86 (itself an authorship-preserving salvage of #26840 by @ArcherQAQ, whose feature commit leads the branch) onto current main, adapted to the backgrounded --skills preload that landed since.

skills:
  auto_load:
    - my-workflow
    - github-pr-workflow

Their mechanism vs ours

  • Cursor: pick a skill → "Use as Mode" → the skill stays pinned in the chat, keeping the agent on a playbook.
  • Hermes: profile-scoped config list; skills are resolved once when the agent's system prompt is first built and the exact rendered bytes are reused across model switches, compression, and static-prefix restoration — so prompt caching stays intact. Missing/disabled skills warn and are skipped. --ignore-rules / HERMES_IGNORE_RULES=1 suppresses auto-load with the rest of the auto-injected context. Explicit --skills requests dedupe against auto-load by canonical name.

Changes

  • agent/skill_commands.py: resolve_auto_load_skills() + build_auto_load_prompt() (purpose-built activation note; same disabled-skill gate and Curator usage bump as --skills)
  • agent/system_prompt.py: resolve-once injection in the shared prompt path (all agent surfaces), lifecycle-stable
  • agent/agent_init.py, hermes_cli/cli_agent_setup_mixin.py: per-agent resolve-once cache, CLI hands its pre-resolved result to the lazily built agent
  • cli.py: auto-load resolution after session-ID creation; adaptation to current main — the --skills payload load is now a background thread joined by finalize_preloaded_skills(), so the dedup set is passed into the background loader and the activated-skills display merges at finalize time (auto_load first)
  • hermes_cli/config_defaults.py: skills.auto_load: [] default
  • Docs: website/docs/user-guide/cli.md (new section from the original PR) + website/docs/user-guide/configuration.md

Validation

Check Result
tests/agent/test_skills_auto_load.py + tests/cli/test_cli_preloaded_skills.py 29 passed
Prompt-cache/system-prompt suites (test_system_prompt, test_prompt_builder, test_prompt_caching, test_prompt_cache_boundary, test_prompt_cache_scope) 183 passed
E2E (isolated HERMES_HOME, real skill files, real build_system_prompt_parts on a real AIAgent) injection ✓, missing-skill warning ✓, resolve-once byte stability after on-disk skill mutation ✓, HERMES_IGNORE_RULES suppression ✓
ruff on all touched files clean
scripts/audit_pr_attribution.py --fix all emails mapped

Closes #26840. Closes #74060.

Infographic

skills.auto_load — pinned skills every session

@github-actions

github-actions Bot commented Aug 22, 2026 •

Copy link
Copy Markdown

૮ >ﻌ< ა ci review

ran on 4b7188c — fix(skills): auto-load resolves under the agent's own home a

⚠️ Warnings

OSV vulnerability scan · View job

76 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.


debug info

CI timings

CI timings · View report · View job

Wall time 6m39s vs 6m9s (+8.1%). 13 job(s) slower, 1 faster, 1 unchanged.

  • OS-specific tests / Windows-only tests: +29.0s
  • Python lints / Windows footguns (blocking): +15.0s
  • Docs Site / docs-site-checks: +13.0s
  • Python tests / e2e: +12.0s
  • OS-specific tests / macOS-only tests: -10.0s

@alt-glitch alt-glitch added type/feature New feature or request comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard tool/skills Skills system (list, view, manage) area/config Config system, migrations, profiles P3 Low — cosmetic, nice to have sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) labels Aug 22, 2026
@Sora-bluesky

Copy link
Copy Markdown

Cross-reference: #68608 (open, CI green) also changes agent/agent_init.py and agent/system_prompt.py, for an unrelated mechanism: it gates the kanban worker protocol (KANBAN_GUIDANCE) on HERMES_KANBAN_TASK instead of kanban_show tool presence, at the session-static resolution in init_agent and at the fallback in build_system_prompt_parts. The hunks sit in different regions from the skills preload here, and a merge of the two heads is clean. I will rebase #68608 once this lands.

@Enough1122

Copy link
Copy Markdown

AI code review — automated review for reference, author can ignore or act on any point.

This salvage does the two hard things right. First, cache safety by construction: auto-load resolves once per agent lifecycle and the exact rendered bytes are reused across model switches, compression, and static-prefix restoration (_auto_load_skills_resolved + seeded result), with HERMES_IGNORE_RULES captured at first resolution so the prompt stays stable even if env changes mid-session — the system prompt remains byte-stable for the conversation's life, which is the invariant that matters most here. Second, contributor credit: authorship-preserving salvage from #74060/#26840 with the contributors email mapping included.

The CLI adaptation to the backgrounded --skills preload is also correct: pre-resolve after session creation (so ${HERMES_SESSION_ID} substitution sees the real ID), seed the agent cache so the shared prompt path doesn't re-read config, pass the canonical-name exclusion set into the background loader, and merge display names auto_load-first at finalize time. E2E validation against a real agent with real skill files, including byte stability after on-disk mutation, is the verification standard the repo asks for on context-affecting paths.

Minor points:

  1. First-turn latency on non-CLI surfaces: gateway/TUI/cron agents resolve lazily inside the first build_system_prompt_parts, so each configured skill's tree walk (~0.5s per the description for large libraries) lands inside the first turn rather than a startup phase. Probably imperceptible for 1–3 skills; worth a doc line so users with long lists know where the cost goes, and a natural follow-up would be warm-preloading where a background phase already exists (as the CLI does).
  2. Missing/disabled entries warn once per agent and skip — good failure direction; consider including whether a similarly-named skill exists in the warning to shorten the typo-debugging loop.
  3. Config edits take effect next session (resolve happens at first build) — consistent with the repo's deferred-invalidation default; no action needed, just confirming that's intended behavior worth stating in configuration.md (the new section covers usage; a one-line "picks up on next session" note would help).

ArcherQAQ and others added 2 commits September 14, 2026 19:03
…rompt

`skills.auto_load: [name, ...]` in config.yaml renders the listed skills
as fully loaded skill blocks in the system prompt of every new agent —
CLI, TUI, gateway, cron and API — the persistent counterpart of `-s`.
Missing or operator-disabled names are warned about and skipped; a
config typo never blocks session start.

Re-implementation of #26840 by @ArcherQAQ (via #74060) against current
main — the original patch targeted the pre-decomposition cli.py /
system_prompt.py god files; design and diagnosis preserved. The loader
reuses `_load_skill_blocks` (same disabled gate and Curator usage bump
as `-s`) instead of a parallel loop.
The system prompt must stay byte-stable for the life of a conversation:
`_auto_load_skills_result` is seeded in `_SESSION_STATE` and filled on
the FIRST prompt build only (HERMES_IGNORE_RULES captured then too), so
model switches, compression and static-prefix restoration reuse the
exact rendered bytes rather than re-reading config or skill files.

CLI: auto_load renders in the existing background `--skills` preload
thread (real session id for ${HERMES_SESSION_ID}), `-s` names dedupe
against the auto-loaded canonical names via
`build_preloaded_skills_prompt(excluded_loaded_names=)`, the activated
skills line shows auto_load first, and the lazily built agent is seeded
with the pre-resolved bytes. `--ignore-rules` skips auto-load with the
rest of the auto-injected context.

Re-implementation of #74060 by @ctaylor86 against current main.
@teknium1
teknium1 force-pushed the cursor-inspired/skills-auto-load branch from 42f27c7 to 756ff37 Compare September 15, 2026 02:06
…internal forks

Why: build_auto_load_prompt read config via ambient load_config_readonly()
and looked skills up under the ambient SKILLS_DIR. Gateway bot threads lose
the HERMES_HOME ContextVar, so a bot profile's pinned skills came from the
launch profile — the docs promise profile scoping. _auto_load_parts now
passes home_override=_agent_home(agent) and build_auto_load_prompt binds it
for config, disabled-list and <home>/skills lookup, the same seam
_skills_prompt uses via skills_dir_override.

_auto_load_parts was unconditional and injected pinned SKILL.md bytes into
delegate children, curator/background_review forks and gateway hygiene
agents; it now mirrors _skills_prompt's gate (nothing without the skills
toolset) and returns [] when skip_context_files is set.

cli.py's HERMES_IGNORE_RULES check used == "1" while system_prompt used
is_truthy_value; both use is_truthy_value now.

Tests stay at 4: the build test asserts the home-scoped resolution, the
ignore-rules test also covers the subagent / no-skills-toolset gates.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades tool/skills Skills system (list, view, manage) type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants